#include <fstream>
#include <G4RunManager.hh>
#include <G4UIExecutive.hh>
#include <G4UImanager.hh>
#include <G4VisExecutive.hh>
#include <globals.hh>
#include <QGSP_BERT.hh>
using namespace std;

#include "DetectorConstruction.hh"
#include "PrimaryGeneratorAction.hh"
#include "StackingAction.hh"
#include "EventAction.hh"
#include "RunAction.hh"
#include "Messenger.hh"

Messenger* messenger = new Messenger();

int main(int argc, char** argv) {
	G4RunManager* runningMan = new G4RunManager();

	DetectorConstruction* construction = new DetectorConstruction();
	runningMan->SetUserInitialization(construction);

	QGSP_BERT* physicsList = new QGSP_BERT();
	runningMan->SetUserInitialization(physicsList);

	PrimaryGeneratorAction* PGA = new PrimaryGeneratorAction();
	runningMan->SetUserAction(PGA);

	StackingAction* USA = new StackingAction();
	runningMan->SetUserAction(USA);

	EventAction* UEA = new EventAction();
	runningMan->SetUserAction(UEA);

	RunAction* URA = new RunAction();
	runningMan->SetUserAction(URA);

	G4VisManager* visMan = new G4VisExecutive();
	visMan->SetVerboseLevel(0);
	visMan->Initialize();

	runningMan->Initialize();

	G4UImanager *UIman = G4UImanager::GetUIpointer();
	UIman->ApplyCommand("/run/verbose 0");
	UIman->ApplyCommand("/event/verbose 0");
	UIman->ApplyCommand("/tracking/verbose 0");

	// Give batch file path as single argument to , and it will execute it,
	// otherwise, it will open a standard UI session

	if (argc > 1) {
		G4String batchPath = argv[1];
		UIman->ApplyCommand("/control/execute " + batchPath);
	} else {
		G4UIExecutive* uiExec = new G4UIExecutive(argc, argv);
		uiExec->SessionStart();
		delete uiExec;
	}

	delete visMan;
	delete runningMan;

	ofstream file("spectrum");

	int* spectrum = messenger->getSpectrum();
	for (int i = 0; i < 200; i++)
		file << i << "\t" << spectrum[i] << endl;

	file.close();

	return 0;
}
